package modeller.queueingnetworksmodel.structure;

import modeller.databasedesignmodel.relation.Relation;
import modeller.databasedesignmodel.transaction.Transaction;
import org.jdom2.Element;

import java.util.HashSet;

import static queped.quepedconstants.Strings.*;

/**
 * Created by:  Jason Ye
 * Date:        29/03/2012
 * Time:        20:59
 */
public class QueueElement extends AbstractNodeChildElement {

    public QueueElement(HashSet<Transaction> transactions, Relation relation) {
        super(transactions, relation);
    }

    @Override
    public Element toXMLRepresentation() {

        Element queue = new Element(XML_E_STATION_SECTION);

        queue.setAttribute(XML_A_STATION_SECTION_CLASSNAME, CLASSNAME_QUEUE);

        // parameters

        // (queue) size
        Element size = generateSize();

        // dropStrategies
        Element dropStrats = generateDropStrategies();

        // PSStrategies
        Element psStrats = generateNewParam(JMTFCFSSTRAT, CLASSNAME_PSSTRATEGY, false);

        // PutStrategy
        Element netStrats = generateNetStrats();

        queue.addContent(size);
        queue.addContent(dropStrats);
        queue.addContent(psStrats);
        queue.addContent(netStrats);

        return queue;

    }

    private Element generateDropStrategies() {

        Element dropStrats = generateNewParam(STRINGCLASSPATH, XML_A_DROPSTRATEGIES, true);

        for (Transaction t : transactions) {

            Element tRefClass = generateNewRefClassElem(t.getTransactionName());
            Element standardDropStrat = generateStandardDropStratElem();
            dropStrats.addContent(tRefClass);
            dropStrats.addContent(standardDropStrat);
        }

        return dropStrats;

    }

    private Element generateNetStrats() {

        Element netStrats = generateNewParam(JMTQUEUEPUTSTRATS, CLASSNAME_NETSTRATEGY, true);

        for (Transaction t : transactions) {

            Element blah = generateNewRefClassElem(t.getTransactionName());
            Element subParam = generateSubParam(JMTTAILSTRAT, CLASSNAME_TAILSTRATEGY);
            netStrats.addContent(blah);
            netStrats.addContent(subParam);

        }

        return netStrats;

    }

    private Element generateGenericPerTransactionStrat(String stratClassName, String stratName, Element strat) {
        Element netStrats = generateNewParam(stratClassName, stratName, true);

        for (Transaction t : transactions) {

            Element transactionName = generateNewRefClassElem(t.getTransactionName());
            netStrats.addContent(transactionName);
            netStrats.addContent(strat);

        }
        return netStrats;
    }

    private Element generateStandardDropStratElem() {

        Element subParam = generateSubParam(STRINGCLASSPATH, XML_A_DROPSTRATEGY);
        Element value = generateValueElem(XML_A_DROP);
        subParam.addContent(value);
        return subParam;

    }

    private Element generateSize() {
        Element size = generateNewParam(INTCLASSPATH, XML_E_PARAMETER_QUEUESIZE, false);

        // VALUE
        Element sizeValue = new Element(XML_E_PARAMETER_VALUE);
        sizeValue.addContent("-1");

        size.addContent(sizeValue);
        return size;
    }

}
